package com.rj.core.validation;


import com.rj.core.exception.BaseException;
import com.rj.util.AssertBeanUtils;
import com.rj.core.validation.constraints.StringField;
import com.rj.util.VerifyUtils;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

/**
 * @author YFX_RANLUBO
 */
public class StrFieldValidator implements ConstraintValidator<StringField, String> {
    /**
     * 对象属性注解
     */
    private StringField checkField;
    /**
     * 是否允许为空
     */
    private boolean allowEmpty;
    /**
     * 属性名称
     */
    private String name;
    /**
     * 最大长度
     *
     * @return
     */
    private Integer maxLen;

    /**
     * 最小长度
     *
     * @return
     */
    private Integer minLen;

    /**
     * 字典key(通过key从存储拉取)
     * 与dict任意填写一个,优先取dict
     *
     * @return
     */
    private String dictKey;

    /**
     * 选项|与dictKey任意填写一个,优先取dict
     *
     * @return
     */
    private String[] dict;

    /**
     * 正则表达式
     */
    private String regexp;
    /**
     * 字符长度
     */
    private int length;

    public StrFieldValidator() {
    }

    @Override
    public void initialize(StringField checkField) {
        this.maxLen = checkField.maxLen();
        this.minLen = checkField.minLen();
        this.length = checkField.length();
        this.regexp = checkField.regexp();
        this.allowEmpty = checkField.empty();
        this.name = checkField.value();
        this.dict = checkField.dict();
        this.dictKey = checkField.dictKey().isEmpty() ? null : checkField.dictKey();
        //dictKey todo

    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        try {
            AssertBeanUtils.check(value, name, allowEmpty)
                    .ifElseApply(minLen > -1 && maxLen > -1,
                            (ut) -> ut.length(minLen, maxLen),
                            (ut) -> ut.ifApply(maxLen > -1, (ut1) -> ut1.maxLen(maxLen))
                                    .ifApply(minLen > -1, (ut1) -> ut1.minLen(minLen))
                    ).ifApply(length > -1, (ut) -> ut.length(length))
                    .ifApply(VerifyUtils.notEmpty(regexp), (ut) -> ut.match(regexp))
                    .ifApply(VerifyUtils.notEmpty(dict), (ut) -> ut.in(dict));
        } catch (BaseException e) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate(e.getMessage()).addConstraintViolation();
            return false;
        }

        return true;
    }
}